/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Controller;

import java.io.EOFException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Nexo
 */
public class ConnReader {

    private String file;
    private int recordNumber;
    private final int RECORDSIZE = 100;
    private RandomAccessFile RAF = null;

    /**
     * Escribe una clase llamada AgendaAleatoria.
     *
     * El método constructor aceptará un parámetro tipo String que será el
     * nombre de un fichero y lo almacenará como atributo de la clase. Además,
     * si archivo ya existía, calculará el número de registros y lo almacenará
     * como atributo de la clase.
     */
    public ConnReader() {
        try {
            file = "./connections.txt";
            if (new File(file).exists()) {
                if (new File(file).isFile()) {
                    RAF = new RandomAccessFile(file, "rw");
                    recordNumber = (int) Math.ceil(RAF.length() / (float) RECORDSIZE);
                } else {
                    System.out.println("ERROR: The fiel does not exists.");
                }
            } else {
                RAF = new RandomAccessFile(file, "rw");
                recordNumber = 0;
            }
            //addFirstConnection();
//            System.out.println("El tamaño del fichero es: " + RAF.length());
//            System.out.println("El numero de registros es: " + RAF.length() / (float) RECORDSIZE);
//            System.out.println("El numero de registros es: " + Math.ceil(RAF.length() / (float) RECORDSIZE));
        } catch (Exception ex) {
            Logger.getLogger(ConnReader.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private void addFirstConnection() {
        Connection connection;
        connection = new Connection("Hostinger", "valdocco.hol.es", "u618667591", "password");
        add(connection);
    }

    /**
     *
     * - getPos(): devuelve el número de registro en el que se encuentra
     * actualmente el puntero de fichero. Emplea para ello el método
     * getFilePointer() de la clase RandomAccessFile, como se indica en las
     * transparencias.
     *
     * @return
     */
    public int getPos() {
        try {
            return (int) Math.ceil(RAF.getFilePointer() / (float) RECORDSIZE);
        } catch (IOException ex) {
            Logger.getLogger(ConnReader.class.getName()).log(Level.SEVERE, null, ex);
        }
        return 0;
    }

    /**
     * - get(int posición): devuelve un objeto Contacto con el nombre y el
     * teléfono de registro que se encuentra en la posición indicada por el
     * parámetro. Si el registro no existe, por ser mayor que numRegs o por
     * haber sido marcado como borrado (ver más adelante), devolverá null.
     *
     * @return
     */
    public Connection get(int posicion) {
        try {
            if (posicion < recordNumber) {
                Connection connection = new Connection();
                RAF.seek(posicion * RECORDSIZE);
                connection.setName(RAF.readUTF());
                connection.setHost(RAF.readUTF());
                connection.setUser(RAF.readUTF());
                connection.setPass(RAF.readUTF());
                return connection;
            }
        } catch (IOException ex) {
            Logger.getLogger(ConnReader.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    /**
     * - set(int posición, Contacto cont): almacenará en el registro que está en
     * la posición indicada el nombre y el teléfono del contacto pasados como
     * parámetro. La posición máxima será numRegs + 1 (para añadir al final). Si
     * el registro ya existía será sobreescrito.
     *
     * @return
     */
    public void set(int pos, Connection conn) {
        if (pos > 0 && pos < recordNumber) {
            try {
                RAF.seek(pos * RECORDSIZE);
                RAF.writeUTF(conn.getName());
                RAF.writeUTF(conn.getHost());
                RAF.writeUTF(conn.getUser());
                RAF.writeUTF(conn.getPass());
            } catch (IOException ex) {
                Logger.getLogger(ConnReader.class.getName()).log(Level.SEVERE, null, ex);
            }
        } else if (pos == recordNumber) {
            add(conn);
        }

    }

    private String getFile() {
        return this.file;
    }

    /**
     * - añadir(Contacto cont): creará un nuevo registro al final del fichero,
     * con el nombre y el teléfono del contacto pasados como parámetro. Empleará
     * para ello el método set().
     */
    public void add(Connection conn) {
        try {
            if (size(conn.getName()) + size(conn.getHost() + size(conn.getUser()) + size(conn.getPass())) < RECORDSIZE) {
                RAF.seek(recordNumber * RECORDSIZE);
                RAF.writeUTF(conn.getName());
                RAF.writeUTF(conn.getHost());
                RAF.writeUTF(conn.getUser());
                RAF.writeUTF(conn.getPass());
                recordNumber++;
            }
        } catch (Exception ex) {
            Logger.getLogger(ConnReader.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * - borrar(int registro): marca el registro como borrado, sustituyendo el
     * nombre por un asterisco.
     *
     * @return
     */
    public void delete(int record) {
        set(record, new Connection("*", "*", "*", "*"));
    }

    /**
     * - buscar(String nombre): busca un nombre en la agenda y, en caso de
     * encontrarlo, devuelve el número de registro en el que se encuentra. En
     * caso contrario devuelve -1. Deberá emplear el método get() para leer los
     * registros.
     *
     * @return
     */
    public int find(String name) {
        int result = -1;
        for (int i = 0; i < recordNumber; i++) {
            if (get(i).getName().equals(name)) {
                result = i;
            }
        }
        return result;
    }

    private int size(Object objeto) {
        int tamaño = 0;
        if (objeto instanceof String) {
            tamaño += tamaño + 2 + objeto.toString().length();
        }
        return tamaño;
    }

    private int recordNumber(RandomAccessFile RAF) {
        return recordNumber;
    }

    /**
     *
     * - leerTodo(): recorrerá todos los registros leyéndolos con get() y
     * mostrando sus datos mediante el método mostrar de la clase Contacto.
     * Habrá evitar intentar mostrar los registros inexistentes o borrados
     * (aquellos para los cuales el método get() devuelve null.
     */
    public void readAll() {
        Connection connection = new Connection();
        for (int i = 0; i < recordNumber; i++) {
            connection = get(i);
            if (!connection.isDeleted()) {
                System.out.print(i + ". ");
                connection.print();
            }
        }
    }

    /**
     * - modificarNombre(int registro, String nombre): modifica el nombre del
     * registro indicado. Deberá usar get() para leer el registro en un objeto
     * Contacto, modificar el nombre en ese objeto y volver a escribir el
     * contacto con set().
     */
    public void modify(int record, String name, String host, String user, String pass) {
        set(record, new Connection(name, host, user, pass));
    }

    public void closeConnReader() {
        try {
            RAF.close();
        } catch (IOException ex) {
            Logger.getLogger(ConnReader.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public Object[] getNames() {
        ArrayList<String> hosts = new ArrayList();
        Connection connection = new Connection();
        for (int i = 0; i < recordNumber; i++) {
            connection = get(i);
            if (!connection.isDeleted()) {
                hosts.add(connection.getName());
            }
        }
        return hosts.toArray();
    }
}
